JavaScript is an easy to learn programming language. It’s easy to write programs that run and does something. However, it’s hard to account for all the uses cases and write robust JavaScript code.
In this article, we’ll look at how to organize our JavaScript code that it’s clean and harder to break.
Keep Functions Simple
Functions are all pieces of code that can be invoked repeatedly with different arguments.
They should be as simple as possible so that they’re easy to test and maintain. Keeping them simple also makes it easier to understand so that everyone can use it or update it if required.
For instance, an example of a simple function is something like the following:
const add = (a, b) => a + b;
The function above is simple. It only does one thing, which is adding 2 numbers together. It’s simple since it only does one operation and returns it.
Also, testing is easy since we only have to test one operation. It’s also easy for us to understand the code.
Divide Code Into Modules
Since ES2015, JavaScript modules is a standard feature of JavaScript. They allow us to divide code into small chunks and expose what’s required. They load asynchronously, which means no tying up the main thread, unlike scripts that are loaded with script tags, which loads synchronously.
Also, the code in functions is hidden from the outside unless we explicitly export the members of a module. This is something that old-style scripts can’t do.
In old-styles scripts, all top-level code is exposed to the outside, which isn’t ideal and it leads to the use of hacky solutions like immediately invoked function expressions (IIFEs) to be used to hide code that we don’t want to expose to the outside.
Also, modules have strict mode turned on by default, so that it’s very hard for us to make mistakes that we would otherwise make if it’s off, like assigning a read-only global variable or value to a different value or declaring global variables accidentally.
Now that we have modules, we don’t have to worry about how to organize our code and hide code from the outside. All we have to do is to export the code that we want to the outside world with the export
keyword.
If we want to use code from another module, then we can import it with the import
keyword.
All imports are read-only versions of the member that’s exported from the originating module. Also, static checks are done to stop us from importing things that don’t exist, which is even better.
Old-style scripts don’t provide any static checks for anything from the outside, so it’s easy for us to make mistakes and make typos in our code, resulting in errors.
This is much better than using script tags since it lets us isolate our code much more easily and provides static checks so that it’s hard for us to make mistakes, creating more robust code in the process.
The common use cases for modules is simple. All we have to do is create JavaScript modules files and then use the export
and import
keywords as follows:
module.js
const foo = 1;
export const bar = 2;
index.js
import { bar } from "./module";
console.log(bar);
In the code above, we create a module by creating module.js
and then adding an export
expression to export our bar
constant.
Since we don’t have export
in front of the first line, we didn’t export foo
, so it won’t be available to the outside.
Then we imported bar
in index.js
and used it in the console log. If we try to import foo
, we’ll get an error because the static analysis will indicate that foo
wasn’t exported, so we can’t import it.
We can also do the import on the fly with the import
function. It returns a promise so it’s also asynchronous.
It allows us to import members from another module dynamically. For instance, in index.js
, we can write the following:
(async () => {
const { bar } = await import("./module");
console.log(bar);
})();
In the code above, we have the import
function call, which imports module.js
as we did before, but we used await
get resolved value, which is an object including bar
.
Then we referenced it in console.log
as we did before.
Conclusion
Keeping functions simple is a good idea if we want to write robust code because it’s easier to read, understand, and test.
JavaScript modules should be used as much as possible to keep code private while exposing others. Only exported code is exposed to the outside.
Also, strict mode is enabled by default in modules. Static analysis is also available for modules to prevent us from making mistakes when referencing code.